package com.sduept.nwld.dataserver.manager.fault;

import com.sduept.bigdata.fault.entity.FaultRecord;
import com.sduept.bigdata.fault.entity.FaultSourceUploadInfo;
import com.sduept.bigdata.fault.manager.FaultRecordQueryManager;
import com.sduept.generator.ObjectId;
import com.sduept.nwld.fault.analysis.model.FaultUploadInfoDTO;
import com.sduept.nwld.fault.analysis.model.StationFaultUploadInfoDTO;
import com.sduept.nwld.fault.analysis.model.StationFaultUploadInfoDTO.FaultUploadInfoSimpleDTO;
import com.sduept.utils.BeanUtil;
import com.sduept.utils.SpringContext;
import org.apache.commons.lang.StringUtils;

import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;

//@Service
//@BusbarFault
public class BusbarFaultUploadTransform implements IFaultUploadTransform {

//	@Autowired
//	private FaultRecordQueryManager fqm;
	FaultRecordQueryManager fqm = SpringContext.getBean(FaultRecordQueryManager.class);
	
	/**
	 * 将故障上送信息按照页面展示格式封装成DTO
	 * 根据List<FaultSourceUploadInfo>获取List<FaultUploadInfoDTO>
	 */
	@Override
	public List<FaultUploadInfoDTO> transform(List<FaultSourceUploadInfo> infos) {
		Map<String, List<FaultSourceUploadInfo>> groupMap = infos.stream().collect(Collectors.groupingBy(FaultSourceUploadInfo::getFaultId));
		List<FaultUploadInfoDTO> result = new ArrayList<FaultUploadInfoDTO>();
		for (String faultId : groupMap.keySet()) {
			List<FaultSourceUploadInfo> lt = groupMap.get(faultId);
			FaultUploadInfoDTO dto = genFaultUploadInfoDTOByFault(faultId,lt);
			result.add(dto);
		}
		return result;
	}
	
	/**
	 * 获取FaultUploadInfoDTO
	 * @param fault
	 * @param list
	 * @return
	 */
	private FaultUploadInfoDTO genFaultUploadInfoDTOByFault(String faultId, List<FaultSourceUploadInfo> list) {
		FaultRecord fault = fqm.findById(faultId);
		FaultUploadInfoDTO dto = setAttributesByFault(fault);
		// 获取FaultUploadInfoDTO的StationFaultUploadInfoDTO
		StationFaultUploadInfoDTO stationInfo = genStationFaultUploadInfoDTO(fault,list);
		dto.getStationInfo().add(stationInfo);
		return dto;
	}
	
	/**
	 * 根据母线故障,设置FaultUploadInfoDTO的属性
	 * @param fr
	 * @return
	 */
	private FaultUploadInfoDTO setAttributesByFault(FaultRecord fr){
		FaultUploadInfoDTO result = new FaultUploadInfoDTO();
		result.setId(ObjectId.get().toString());
		result.setRecordId(fr.getId());
		result.setEtype(fr.getEtype());
		result.setFaultDesc(fr.getEquipment()+"故障");
		result.setFaultDevice(fr.getEquipment());
		result.setFaultTime(fr.getFaultTime());
		return result;
	}
	
	/**
	 * 获取List<StationFaultUploadInfoDTO>
	 * @param valueMap
	 * @return
	 */
	private StationFaultUploadInfoDTO genStationFaultUploadInfoDTO(FaultRecord fault,List<FaultSourceUploadInfo> list) {
		StationFaultUploadInfoDTO sdto = new StationFaultUploadInfoDTO();
//		BusbarSection busbar = cim.getBusbarSectionsById(fault.getEquipment_id());
//		sdto.setStationName(busbar.getSubName());
		sdto.setStationName(fault.getStationName());
		genStationFaultUploadInfoDTO(list,sdto);
		return sdto;
	}
	
	/**
	 * 将一个故障中一个变电站对应的多个FaultUploadInfo，封装成StationFaultUploadInfoDTO
	 * @param list
	 * @return
	 */
	private void genStationFaultUploadInfoDTO(List<FaultSourceUploadInfo> list,StationFaultUploadInfoDTO dto) {
		int deviceType = -1; // 设备类型：0：录波器，1：主保护， 2：断路器保护，3：非电量保护
		List<FaultUploadInfoSimpleDTO> mainProtectList = new ArrayList<FaultUploadInfoSimpleDTO>();
		List<FaultUploadInfoSimpleDTO> breakerProtectList = new ArrayList<FaultUploadInfoSimpleDTO>();
		for (FaultSourceUploadInfo info : list) {
			deviceType = info.getDeviceType();
			if(0 == deviceType) {
				setCenterWaveUploadMethod(info, dto); // 设置集中录波上送方式
			} else if (1 == deviceType) {
				setMainProtectUploadMethod(info, dto); // 设置主保护录波和元件的上送方式
				FaultUploadInfoSimpleDTO fui = assembleUploadDTO(info);
				mainProtectList.add(fui);
			} else if (2 == deviceType) {
				setBreakerProtectUploadMethod(info, dto); // 设置断路器保护录波和元件的上送方式
				FaultUploadInfoSimpleDTO fui = assembleUploadDTO(info);
				breakerProtectList.add(fui);
			}
		}
		List<FaultUploadInfoSimpleDTO> mainList = assembleSimpleUploadDTO(mainProtectList);
		sortFaultUploadListByName(mainList);
		dto.setMainProtectList(mainList);
		List<FaultUploadInfoSimpleDTO> brpList = assembleSimpleUploadDTO(breakerProtectList);
		sortFaultUploadListByName(brpList);
		dto.setBreakerProtectList(brpList);
	}
	
	/**
	 * 按照名称排序
	 * @param result
	 */
	private void sortFaultUploadListByName(List<FaultUploadInfoSimpleDTO> faultUploadList) {
		Collections.sort(faultUploadList, new Comparator<FaultUploadInfoSimpleDTO>() {
			@Override
			public int compare(FaultUploadInfoSimpleDTO fault1, FaultUploadInfoSimpleDTO fault2) {
				String name1 = fault1.getName();
				String name2 = fault2.getName();
				if(StringUtils.isEmpty(name1) || StringUtils.isEmpty(name2)) {
					return 1;
				}
				return name1.compareTo(name2);
			}
		});
	}
	
	/**
	 * 组织上送数据DTO
	 * @param info
	 * @return
	 */
	private FaultUploadInfoSimpleDTO assembleUploadDTO(FaultSourceUploadInfo info) {
		FaultUploadInfoSimpleDTO fui = new FaultUploadInfoSimpleDTO();
		fui.setId(info.getId());
		fui.setName(info.getName());
		fui.setEquipId(info.getEquipId());
		if(0 == info.getUploadType()) {
			fui.setWaveInfo(info.getUploadMethod());
		}else {
			fui.setDatagramInfo(info.getUploadMethod());
		}
		return fui;
	}
	
	/**
	 * 根据所给的简略版故障上送信息，将录波、报文根据equipId合并成一条记录
	 * @param protectList
	 * @return
	 */
	private List<FaultUploadInfoSimpleDTO> assembleSimpleUploadDTO(List<FaultUploadInfoSimpleDTO> protectList) {
		List<FaultUploadInfoSimpleDTO> protect = new ArrayList<FaultUploadInfoSimpleDTO>();
		Map<String, List<FaultUploadInfoSimpleDTO>> uploadInfoMap = new HashMap<String, List<FaultUploadInfoSimpleDTO>>();//故障上送数据<设备id，上送数据简略信息>
		for(FaultUploadInfoSimpleDTO fuisd : protectList) {
			List<FaultUploadInfoSimpleDTO> infoList = uploadInfoMap.get(fuisd.getEquipId());
			if(infoList == null) {
				infoList = new ArrayList<FaultUploadInfoSimpleDTO>();
				infoList.add(fuisd);
				uploadInfoMap.put(fuisd.getEquipId(), infoList);
			}else {
				infoList.add(fuisd);
			}
		}
		for(Map.Entry<String, List<FaultUploadInfoSimpleDTO>> entry : uploadInfoMap.entrySet()) {
			List<FaultUploadInfoSimpleDTO> infoList = entry.getValue();
			FaultUploadInfoSimpleDTO info1 = infoList.get(0);
			FaultUploadInfoSimpleDTO info2 = infoList.get(1);
			try {
				BeanUtil.copyBean(info2, info1);
				protect.add(info1);
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		}
		return protect;
	}
	
	/**
	 * 设置集中录波的上送方式
	 * @param info
	 * @param dto
	 * @return
	 */
	private void setCenterWaveUploadMethod(FaultSourceUploadInfo info, StationFaultUploadInfoDTO dto) {
		if(0==info.getUploadType() && 0==info.getDeviceType()) {
			dto.setWaveInfo(info.getUploadMethod());
		}
	}
	/**
	 * 设置主保护录波和元件的上送方式
	 * @param info
	 * @param dto
	 * @return
	 */
	private void setMainProtectUploadMethod(FaultSourceUploadInfo info, StationFaultUploadInfoDTO dto) {
		// 主保护录波
		if(0==info.getUploadType() && 1==info.getDeviceType()) {
			if(info.getName().contains("主一")) {
				dto.setMain1WaveInfo(info.getUploadMethod());
			} else if (info.getName().contains("主二")) {
				dto.setMain2WaveInfo(info.getUploadMethod());
			}
		}
		// 主保护元件
		if(1==info.getUploadType() && 1==info.getDeviceType()) {
			if(info.getName().contains("主一")) {
				dto.setMain1DatagramInfo(info.getUploadMethod());
			} else if (info.getName().contains("主二")) {
				dto.setMain2DatagramInfo(info.getUploadMethod());
			}
		}
	}
	/**
	 * 设置断路器保护录波和元件的上送方式
	 * @param info
	 * @param dto
	 * @return
	 */
	private void setBreakerProtectUploadMethod(FaultSourceUploadInfo info, StationFaultUploadInfoDTO dto) {
		// 断路器保护录波
		if(0==info.getUploadType() && 2==info.getDeviceType()) {
			if(StringUtils.isEmpty(dto.getBreakerProtect1Name()) || info.getName().equals(dto.getBreakerProtect1Name())) {
				dto.setBreakerProtect1Name(info.getName());
				dto.setBreakerProtect1WaveInfo(info.getUploadMethod());
			} else if(StringUtils.isEmpty(dto.getBreakerProtect2Name()) || info.getName().equals(dto.getBreakerProtect2Name())){
				dto.setBreakerProtect2Name(info.getName());
				dto.setBreakerProtect2WaveInfo(info.getUploadMethod());
			} else if (StringUtils.isEmpty(dto.getBreakerProtect3Name()) || info.getName().equals(dto.getBreakerProtect3Name())) {
				dto.setBreakerProtect3Name(info.getName());
				dto.setBreakerProtect3WaveInfo(info.getUploadMethod());
			} else if (StringUtils.isEmpty(dto.getBreakerProtect4Name()) || info.getName().equals(dto.getBreakerProtect4Name())) {
				dto.setBreakerProtect4Name(info.getName());
				dto.setBreakerProtect4WaveInfo(info.getUploadMethod());
			} else if (StringUtils.isEmpty(dto.getBreakerProtect5Name()) || info.getName().equals(dto.getBreakerProtect5Name())) {
				dto.setBreakerProtect5Name(info.getName());
				dto.setBreakerProtect5WaveInfo(info.getUploadMethod());
			} else if (StringUtils.isEmpty(dto.getBreakerProtect6Name()) || info.getName().equals(dto.getBreakerProtect6Name())) {
				dto.setBreakerProtect6Name(info.getName());
				dto.setBreakerProtect6WaveInfo(info.getUploadMethod());
			}
		}
		// 断路器保护元件
		if(1==info.getUploadType() && 2==info.getDeviceType()) {
			if(StringUtils.isEmpty(dto.getBreakerProtect1Name()) || info.getName().equals(dto.getBreakerProtect1Name())) {
				dto.setBreakerProtect1Name(info.getName());
				dto.setBreakerProtect1DatagramInfo(info.getUploadMethod());
			} else if(StringUtils.isEmpty(dto.getBreakerProtect2Name()) || info.getName().equals(dto.getBreakerProtect2Name())){
				dto.setBreakerProtect2Name(info.getName());
				dto.setBreakerProtect2DatagramInfo(info.getUploadMethod());
			} else if(StringUtils.isEmpty(dto.getBreakerProtect3Name()) || info.getName().equals(dto.getBreakerProtect3Name())){
				dto.setBreakerProtect3Name(info.getName());
				dto.setBreakerProtect3DatagramInfo(info.getUploadMethod());
			} else if(StringUtils.isEmpty(dto.getBreakerProtect4Name()) || info.getName().equals(dto.getBreakerProtect4Name())){
				dto.setBreakerProtect4Name(info.getName());
				dto.setBreakerProtect4DatagramInfo(info.getUploadMethod());
			} else if(StringUtils.isEmpty(dto.getBreakerProtect5Name()) || info.getName().equals(dto.getBreakerProtect5Name())){
				dto.setBreakerProtect5Name(info.getName());
				dto.setBreakerProtect5DatagramInfo(info.getUploadMethod());
			} else if(StringUtils.isEmpty(dto.getBreakerProtect6Name()) || info.getName().equals(dto.getBreakerProtect6Name())){
				dto.setBreakerProtect6Name(info.getName());
				dto.setBreakerProtect6DatagramInfo(info.getUploadMethod());
			}
		}
	}
	
	/**
	 * 获取所有的断路器属性，断路器1录波、事件，断路器2录波、事件。。。
	 * @return
	 */
	@Deprecated
	private List<Field> getAllBreakerAttributes() {
		List<Field> list = new ArrayList<Field>();
		Field[] fields = StationFaultUploadInfoDTO.class.getDeclaredFields();
		for (Field field : fields) {
			String fieldName = field.getName();
			if(fieldName.startsWith("breakerProtect")) {
				list.add(field);
			}
		}
		return list;
	}

}
